package com.samphanie.auiu.auth.utils;

import com.samphanie.auiu.auth.validation.code.captcha.ValidateCodeProcessorHolder;
import com.samphanie.auiu.auth.validation.code.captcha.enums.ValidateCodeType;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.util.Optional;

/**
 * @author ZSY
 * @email 1451691457@qq.com
 */
@Slf4j
public class SecurityUtil {

    private static final String ANONYMOUS_USER = "anonymous";
    private static ValidateCodeProcessorHolder validateCodeProcessorHolder;
    public void setValidateCodeProcessorHolder(ValidateCodeProcessorHolder codeProcessorHolder){
        validateCodeProcessorHolder = codeProcessorHolder;
    }

    public static String getCurrentUsername() {
        return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
                .map(Authentication::getPrincipal)
                .map(principal -> {
                    // 大多数 AuthenticationManager 会返回 UserDetails ，提供更多信息
                    if (principal instanceof UserDetails) {
                        val userDetails = (UserDetails) principal;
                        return userDetails.getUsername();
                    }
                    // 如果没有更多信息，可以看一下是否是一个 Principal
                    if (principal instanceof Principal) {
                        return ((Principal) principal).getName();
                    }
                    // 其他情况看作是一个用户名
                    return String.valueOf(principal);
                })
                // 如果未认证，那么 Authentication 为 Null
                // 可以在未受安全保护的 URL 中实验
                // 此次返回匿名用户
                .orElse(ANONYMOUS_USER);
    }

    public static void checkSmsCode(String code, HttpServletRequest request, HttpServletResponse response) {
        if (!request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            ValidateCodeType type = ValidateCodeType.SMS;
            log.debug("校验请求(" + request.getRequestURI() + ")中的验证码,验证码类型" + type);
            validateCodeProcessorHolder.findValidateCodeProcessor(type)
                    .validate(new ServletWebRequest(request, response), code);
            log.debug("验证码校验通过");
        }
    }

}
